#include <iostream>
#include <pthread.h>
#include <queue>
#include <unistd.h>

#define NUM 5

//创建一个容器为5的生消模型

template<class T>
class BlockQueue{
    private:
    //判满判空操作
    bool Iffull(){ return _qe.size() == _cap;}
    bool Ifempty(){ return _qe.empty();}
    public:
    //构造和析构函数
    BlockQueue(int cap = NUM):_cap(cap){
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_full,nullptr);
        pthread_cond_init(&_empty,nullptr);
    }
    ~BlockQueue(){
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_full);
        pthread_cond_destroy(&_empty);
    }
    //插入（生产者用
    void Push(const T& data){
        pthread_mutex_lock(&_mutex);
        while(Iffull()){
            //满了要进行等待
            pthread_cond_wait(&_full,&_mutex);
        }
        _qe.push(data);
        //当大于时才消费
        if(_qe.size() >= _cap/2) pthread_cond_signal(&_empty);
        pthread_mutex_unlock(&_mutex);
        
    }
     //取出（消费者用
    //输入输出参数
    void Pop(T& data){
        pthread_mutex_lock(&_mutex);
        while(Ifempty()){
            pthread_cond_wait(&_empty,&_mutex);
        }
        data = _qe.front();
        _qe.pop();
        if(_qe.size() <= _cap / 2) pthread_cond_signal(&_full);
        pthread_mutex_unlock(&_mutex);
        
    }
   
    private:
    std::queue<T> _qe;
    int _cap;//阻塞队列最大容器个数

    pthread_mutex_t _mutex;
    //满和空的条件变量，用于强行停止一方
    pthread_cond_t _full;
    pthread_cond_t _empty;
};